package main

import (
	"net"
	"os"
	"fmt"
	"log"
	"git.oschina.net/solate/test/other/tcp/protocol"
	"time"
)

func main() {

	//建立tcp连接
	netListen, err := net.Listen("tcp", "localhost:9998")
	checkErr(err)
	defer netListen.Close()


	log.Println("waiting for clients")
	for   {
		conn, err := netListen.Accept()
		if err != nil {
			log.Println("conn err:", err.Error())
			continue
		}


		//设置超时时间
		conn.SetReadDeadline(time.Now().Add(10 * time.Second))
		log.Println("tcp connect success:", conn.RemoteAddr().String())
		go handleConn(conn)

	}

}

//长连接入口
func handleConn(conn net.Conn)  {

	timeout := 10


	//这里改成2048, 因为如果是1024正好读不完一个消息，所以这个是后面处理如果是半包的问题该怎么解决
	//这里只展示了沾包的时候处理方式：用协议
	buffer := make([]byte, 2048)

	for {
		n, err := conn.Read(buffer)
		if err != nil {
			log.Println(conn.RemoteAddr().String()," conn read err:", err.Error())
			return
		}

		Data := (buffer[:n])
		messager := make(chan byte)

		go HearBeating(conn, messager, timeout)
		//检测每次Client是否有数据传来
		go GravelChannel(Data,messager)

		log.Println(conn.RemoteAddr().String(), "receive data length:\n", n)
		log.Println(conn.RemoteAddr().String(), "receive data length:\n", n)

	}

}

//心跳计时，根据GravelChannel判断Client是否在设定时间内发来信息
func HearBeating(conn net.Conn, readerChannel chan byte,timeout int)  {
	select {
	case fk := <- readerChannel:
		log.Println(conn.RemoteAddr().String(), "receive data string:", string(fk))
		conn.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Second))
		break
	case <-time.After(time.Second*5):
		log.Println("It's really weird to get Nothing!!!")
		conn.Close()
	}
}

func GravelChannel(n []byte,mess chan byte){
	for _ , v := range n{
		mess <- v
	}
	close(mess)
}


func checkErr(err error)  {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error:%s", err.Error())
		os.Exit(1)
	}
}